home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 / Aminet - June 1993 [Walnut Creek].iso / ab20 / languags / cpp / gcgp1409.lha / hunk2gcc / hunk2gcc.c next >
Encoding:
C/C++ Source or Header  |  1992-01-27  |  21.6 KB  |  756 lines

  1. ;/* how to compile this thingy:
  2. gcc2 -s -O2 -mc68000 -DNDEBUG hunk2gcc.c -o hunk2gcc
  3. quit
  4. */
  5.  
  6. /*
  7.  * Convert amiga object files in the hunk format into a.out-object files.
  8.  * ALINK style (ie. concatenated) libraries are supported as well, in that
  9.  * case a collection of object files is generated, you'll have to run
  10.  * `ar rs libfoo.a obj.*' on them to make an a.out-style library out of 
  11.  * them.
  12.  *
  13.  * Currently untested are:
  14.  *  o  base-relative relocs and references
  15.  *     I'll first have to teach gnu-ld how to deal with them ;-)
  16.  *  o  conversion of load files...
  17.  *  o  common symbols, amiga objects normally don't use them, sigh
  18.  *
  19.  * Currently not implemented are:
  20.  *  o  BLINK style indexed libraries (HUNK_LIB and HUNK_INDEX). If you're
  21.  *     generating such libraries yourself, you can as well generate oldstyle
  22.  *     libraries, and the libraries from Commodore-Amiga are in ALINK format
  23.  *     (amiga.lib and friends).
  24.  *     This index-format is so weird and complicated that I didn't bother
  25.  *     long to decide not to support it. If someone volunteers (you got
  26.  *     the source;-)) please send me enhancements!
  27.  *
  28.  * V1.0  91-10-08  M.Wild  first hack
  29.  * V1.01 92-01-20  M.Wild  some pcrel code commented out, something is weird there..
  30.  *
  31.  * This is free software. This means that I don't care what you do with it
  32.  * as long as you don't claim you wrote it. If you enhance it, please
  33.  * send me your diffs! 
  34.  * Oh, of course, you use this stuff entirely at your own risk, I'm not 
  35.  * responsible for any damage this program might cause to you, your computer,
  36.  * your data, your cat, your whateveryoucanthinkof, no warranty whatsoever is
  37.  * granted.
  38.  *
  39.  * I can be reached on internet as: wild@nessie.cs.id.ethz.ch (Markus Wild)
  40.  *
  41.  */
  42.  
  43. #include <sys/types.h>
  44. #include <sys/stat.h>
  45. #include <sys/file.h>
  46. /* sun3-a.out file */
  47. #include <a.out.h>
  48. #include <stdio.h>
  49. #include <stdlib.h>
  50.  
  51. /* This is really <dos/doshunks.h>, which is a 2.0 header file.
  52.  * You can get those 2.0 headers from CATS.
  53.  * Sorry, I'm not allowed to include them here. You may as well take the
  54.  * AmigaDOS Manual 2nd ed. (you'll miss the a4-rel hunks) or 3rd ed. and write
  55.  * the header yourself, it's not that long and difficult
  56.  */
  57. #include "doshunks.h"
  58.  
  59.  
  60. #ifndef NDEBUG
  61. #define DP(a) printf a
  62. #else
  63. #define DP(a)
  64. #endif
  65.  
  66.  
  67. extern int errno;
  68.  
  69. /* my favorite typedefs ;-)) */
  70. typedef unsigned char uchar;
  71. typedef unsigned long ulong;
  72.  
  73. ulong *file_buf = 0;
  74.  
  75. struct reloc {
  76.   /* at which offset to relocate */
  77.   int offset;
  78.   /* based on which hunk base */
  79.   int from_hunk, to_hunk;
  80.   int size;
  81.   int pcrel;
  82.   int baserel;
  83.   /* if != -1, the "to_hunk" field is not used */
  84.   int sym_num;
  85. };
  86.  
  87. /* NOTE: this symbol definition is compatible with struct nlist, and it will
  88.  * be converted into a struct nlist in 'emit_aout_obj' */
  89. struct symbol {
  90.   int   name;        /* string as offset into string table */
  91.   uchar type;
  92.   uchar pad1;        /* really n_other */
  93.   short hunk_num;    /* really n_desc  */
  94.   ulong value;
  95. };
  96.  
  97. struct table {
  98.   void *base;
  99.   int el_size;
  100.   int i;
  101.   int max_el;
  102. };
  103.  
  104. void
  105. emit_aout_file (int fd, void *text, void *data, struct exec *hdr,
  106.         struct table *ch_tab, struct table *dh_tab, struct table *bh_tab,
  107.         struct table *reloc_tab,  struct table *symbol_tab, int max_hunk);
  108.  
  109. #define TAB_START_SIZE 1024
  110.  
  111. /* advance the hunk-pointer to the next hunk. Assumes the hunk-pointer is
  112.  * pointing at the length-field currently
  113.  */
  114. static void inline 
  115. next_hunk(ulong **hp)
  116. {
  117.   /* skip over the length field and the there given length */
  118.   *hp += 1 + **hp;
  119. }
  120.  
  121. /****************************************************************************/
  122.  
  123. /* these two function maintain the string table. You may only free the last
  124.  * string allocated. (This could be done with an obstack as well, but I really
  125.  * don't need the whole functionality of an obstack, so I kept it simple ;-))
  126.  * Only use the offset, since the table itself may be reallocated.
  127.  */
  128. char *str_table = 0;
  129. int strtab_size, strtab_index;
  130.  
  131. static int inline
  132. stralloc (int len)
  133. {
  134.   int res;
  135.  
  136.   /* always include the zero terminator */
  137.   len++;
  138.  
  139.   if (! str_table)
  140.     {
  141.       strtab_size = TAB_START_SIZE;
  142.       /* start the table at index 4, leaving space to later fill in the 
  143.        * size of the table */
  144.       strtab_index = 4;
  145.       str_table = malloc (strtab_size);
  146.     }
  147.  
  148.   while (strtab_index + len > strtab_size)
  149.     {
  150.       strtab_size <<= 1;
  151.       str_table = realloc (str_table, strtab_size);
  152.     }
  153.   
  154.   res = strtab_index;
  155.   strtab_index += len;
  156.   return res;
  157. }
  158.  
  159. static void inline
  160. strfree (int str)
  161. {
  162.   strtab_index = str;
  163. }
  164.  
  165. /****************************************************************************/
  166.  
  167. static void inline
  168. add_table (struct table *tab, void *el)
  169. {
  170.   if (tab->i == tab->max_el)
  171.     {
  172.       if (! tab->base)
  173.         {
  174.           tab->max_el = TAB_START_SIZE;
  175.           tab->base = malloc (tab->max_el * tab->el_size);
  176.         }
  177.       else
  178.     {
  179.       tab->max_el <<= 1;
  180.       tab->base = realloc (tab->base, tab->max_el * tab->el_size);
  181.     }
  182.       if (! tab->base)
  183.         {
  184.       fprintf (stderr, "Out of memory adding to table.\n");
  185.       /* exit does close all outstanding files ;-) */
  186.       exit (20);
  187.     }
  188.     }
  189.   bcopy (el, (uchar *)tab->base + (tab->i++ * tab->el_size), tab->el_size);
  190. }
  191.  
  192. static void inline
  193. add_reloc (struct table *tab, int from, int to, int offset,
  194.            int size, int pcrel, int baserel, int sym_num)
  195. {
  196.   struct reloc r;
  197.  
  198. DP(("reloc: from=%d, to=%d, off=%d, size=%d, pc=%d, ba=%d, syn=%d\n",
  199.     from, to, offset, size, pcrel, baserel, sym_num));
  200.  
  201.   r.from_hunk = from;
  202.   r.to_hunk   = to;
  203.   r.offset    = offset;
  204.   r.size      = size;
  205.   r.pcrel     = pcrel;
  206.   r.baserel   = baserel;
  207.   r.sym_num   = sym_num;
  208.   add_table (tab, &r);
  209. }
  210.  
  211. static void inline
  212. add_symbol (struct table *tab, int num, ulong type, int value, char *name)
  213. {
  214.   struct symbol s;
  215.   
  216.   s.hunk_num = num;
  217.   s.type     = type >> 24;
  218.   s.value    = value;
  219.   s.name     = stralloc ((type & 0xffffff)<<2);
  220.   bcopy (name, str_table+s.name, (type & 0xffffff)<<2);
  221.   (str_table+s.name)[(type & 0xffffff)<<2] = 0;
  222.   
  223.   /* some (really stupid..) compilers mention symbols twice, once as 
  224.    * a definition, and once as an EXT_SYMB. So we really have to search 
  225.    * the symbol_table before adding an EXT_SYMB and check if a symbol of this name
  226.    * isn't already defined for this value. If this hack should slow down
  227.    * the conversion dramatically, I'll have to resort to hashing, I don't
  228.    * like that idea... */
  229.   if (s.type == EXT_SYMB)
  230.     {
  231.       int i;
  232.       
  233.       for (i = 0; i < tab->i; i++)
  234.     /* we have CSE in the compiler, right? ;-)) */
  235.     if (((struct symbol *)tab->base)[i].value    == s.value    &&
  236.         ((struct symbol *)tab->base)[i].hunk_num == s.hunk_num &&
  237.         ! strcmp (str_table+((struct symbol *)tab->base)[i].name,
  238.               str_table+s.name))
  239.       {
  240.         strfree (s.name);
  241.         return;
  242.       }
  243.     }
  244.   
  245.   add_table (tab, &s);
  246. }
  247.  
  248. /****************************************************************************/
  249.  
  250. void
  251. digest_objfile (ulong **file_pptr, ulong *max_fp)
  252. {
  253.   /* this makes it less clumsy.. */
  254.   ulong *file_ptr = *file_pptr;
  255.   static int obj_file_num = 0;
  256.   int units = 0;
  257.   /* to be filled in by the hunk_unit name parameter */
  258.   int fd = -1;
  259.   
  260.   /* buffer-pointers, where text, data & bss sections are stored.
  261.    * Currently only one hunk with size!=0 of type text/data/bss each is
  262.    * supported */
  263.   uchar *text, *data;
  264.   struct exec hdr;
  265.   
  266.   /* hunk numbers, needed to associate reloc blocks with segments */ 
  267.   int hunk_num;
  268.   static struct table code_hunks = { 0, 4, 0, 0 };
  269.   static struct table data_hunks = { 0, 4, 0, 0 };
  270.   static struct table  bss_hunks = { 0, 4, 0, 0 };
  271.  
  272.   /* static so that no initialization code is required */
  273.   static struct table reloc_tab  = { 0, sizeof (struct reloc), 0, 0 };
  274.   static struct table symbol_tab = { 0, sizeof (struct symbol), 0, 0 };
  275.  
  276.   /* (re) init tables */
  277.   strtab_index = 4;
  278.   code_hunks.i =
  279.     data_hunks.i =
  280.       bss_hunks.i =
  281.         reloc_tab.i =
  282.           symbol_tab.i = 0;
  283.   
  284.   
  285.   while (units < 2)
  286.     {
  287.       switch (*file_ptr++)
  288.         {
  289.         case HUNK_UNIT:
  290. DP(("HUNK_UNIT: units = %d\n", units));
  291.           if (units++) break;
  292. #if 0
  293.       if (! file_ptr[0])
  294. #endif
  295.         {
  296.           /* need [], not *, so that gcc allocates a fresh copy for
  297.            * mkstemp() to modify! */
  298.           char tmp_nam[] = "obj.YYYY.XXXXXX";
  299.           /* this trick makes mkstemp() lots faster ;-) */
  300.           sprintf (tmp_nam, "obj.%04d.XXXXXX", obj_file_num++);
  301.           if ((fd = mkstemp (tmp_nam)) < 0)
  302.               fprintf (stderr, "Can't create object file: %s. Ignoring it.\n",
  303.                        tmp_nam, strerror (errno));
  304.         }
  305. #if 0
  306. /* this idea was too good.. there are so many stupid (and duplicate!) names
  307.  * of program units, that this generated ridiculous results... */
  308.  
  309.       else
  310.         {
  311.           char *file_name;
  312.           file_name = alloca (file_ptr[0] + 1);
  313.           strncpy (file_name, (char *)&file_ptr[1], file_ptr[0]);
  314.           if ((fd = open (file_name, O_RDWR|O_CREAT|O_EXCL, 0666)) < 0)
  315.               fprintf (stderr, "Can't create %s: %s. Ignoring it.\n",
  316.                        file_name, strerror (errno));
  317.         }
  318. #endif
  319.  
  320.       /* init data for new object file */
  321.       text = data = 0;
  322.       bzero (&hdr, sizeof (hdr));
  323.       /* if someone want's to use'em on a sun, why shouldn't we make
  324.        * the files sun-conformant? */
  325.       hdr.a_toolversion = TV_SUN2_SUN3;
  326.       hdr.a_machtype = M_68010;    /* not restricted to 68020 only */
  327.       hdr.a_magic = OMAGIC;        /* relocatable format */
  328.       hunk_num = 0;
  329.       next_hunk (& file_ptr);
  330.       break;
  331.  
  332.         case HUNK_NAME:
  333.         case HUNK_DEBUG:
  334. DP(("HUNK_NAME/DEBUG\n"));
  335.       /* this hunk is silently ignored ;-) */
  336.       next_hunk (& file_ptr);
  337.       break;
  338.     
  339.         case HUNK_OVERLAY:
  340.           fprintf (stderr, "warning: overlay hunk ignored!\n");
  341.           next_hunk (& file_ptr);
  342.           break;
  343.         
  344.         case HUNK_BREAK:
  345.           fprintf (stderr, "warning: break hunk ignored!\n");
  346.       break;
  347.     
  348.         case HUNK_HEADER:
  349.           fprintf (stderr, "warning: load file header encountered.\n");
  350.           fprintf (stderr, "         are you sure this is an object file?\n");
  351.           /* nevertheless, we go on. perhaps some day I need this feature to
  352.            * be able to convert a loadfile into an object file?! */
  353.          
  354.           /* skip (never used) resident library names */
  355.           while (file_ptr[0]) next_hunk (& file_ptr);
  356.           /* skip null-word, table_size, F & L, and size-table */
  357.           file_ptr += 4 + (file_ptr[1] - file_ptr[2] + 1);
  358.           break;
  359.         
  360.         case HUNK_CODE:
  361. DP(("HUNK_CODE, size = $%x\n", file_ptr[0] << 2));
  362.       if (file_ptr[0])
  363.         {
  364.           /* only accept one code hunk with size != 0 */
  365.           if (hdr.a_text)
  366.             fprintf (stderr, "only one code hunk with size!=0 supported.\n");
  367.           else
  368.             {
  369.                 text = (uchar *)&file_ptr[1];
  370.                 hdr.a_text = file_ptr[0] << 2;
  371.             }
  372.         }
  373.       next_hunk (& file_ptr);
  374.       add_table (& code_hunks, &hunk_num);
  375.       hunk_num++;
  376.       break;
  377.  
  378.         case HUNK_DATA:
  379. DP(("HUNK_DATA, size = $%x\n", file_ptr[0] << 2));
  380.       if (file_ptr[0])
  381.         {
  382.           /* only accept one data hunk with size != 0 */
  383.           if (hdr.a_data)
  384.             fprintf (stderr, "only one data hunk with size!=0 supported.\n");
  385.           else
  386.             {
  387.                 data = (uchar *)&file_ptr[1];
  388.                 hdr.a_data = file_ptr[0] << 2;
  389.             }
  390.         }
  391.       next_hunk (& file_ptr);
  392.       add_table (& data_hunks, & hunk_num);
  393.       hunk_num++;
  394.       break;
  395.  
  396.         case HUNK_BSS:
  397. DP(("HUNK_BSS, size = $%x\n", file_ptr[0] << 2));
  398.       if (file_ptr[0])
  399.         {
  400.           /* only accept one bss hunk with size != 0 */
  401.           if (hdr.a_bss)
  402.             fprintf (stderr, "only one bss hunk with size!=0 supported.\n");
  403.           else
  404.             hdr.a_bss = file_ptr[0] << 2;
  405.         }
  406.       file_ptr++;
  407.       add_table (& bss_hunks, & hunk_num);
  408.       hunk_num++;
  409.       break;
  410.  
  411.         case HUNK_RELOC8:
  412.         case HUNK_RELOC16:
  413.         case HUNK_RELOC32:
  414.         /* do they work like this? don't know... */
  415.         case HUNK_DREL8:
  416.         case HUNK_DREL16:
  417.         case HUNK_DREL32:
  418.       {
  419.         int size, brel;
  420.  
  421.         brel = file_ptr[-1] >= HUNK_DREL32;
  422.         size = (brel ? HUNK_DREL8 : HUNK_RELOC8) - file_ptr[-1];
  423. DP(("HUNK_RELOC/DREL ($%x), brel = %d, size = %d\n", file_ptr[-1], brel, size));
  424.                 
  425.         while (file_ptr[0])
  426.           {
  427.             long to_reloc = file_ptr[1];
  428.             long n        = file_ptr[0];
  429.  
  430.             while (n--)
  431.               /* amiga relocs are automatically pcrel, when size < 2
  432.            * according to the AmigaDOS-Manual 2nd ed. */
  433.               add_reloc (&reloc_tab, hunk_num-1, to_reloc, file_ptr[n+2],
  434.                          size, size != 2, brel, -1);
  435.         
  436.             file_ptr += file_ptr[0] + 2;
  437.           }
  438.       }
  439.           file_ptr++;
  440.           break;
  441.         
  442.         case HUNK_SYMBOL:
  443.         case HUNK_EXT:
  444. DP(("HUNK_SYMBOL/EXT\n"));
  445.       while (file_ptr[0])
  446.         {
  447.           int n, size, brel;
  448.  
  449. DP(("  EXT_: %d, %-*.*s\n", file_ptr[0] >> 24, 
  450.     4*(file_ptr[0] & 0xffffff), 4*(file_ptr[0] & 0xffffff), &file_ptr[1]));
  451.  
  452.           switch (file_ptr[0] >> 24)
  453.             {
  454.               case EXT_SYMB:
  455.               case EXT_DEF:
  456.               case EXT_ABS:
  457.               case EXT_RES:
  458.                 add_symbol (&symbol_tab, hunk_num-1, file_ptr[0], 
  459.                     file_ptr[1+(file_ptr[0] & 0xffffff)],
  460.                     (char *)&file_ptr[1]);
  461.             file_ptr += 2+(file_ptr[0] & 0xffffff);
  462.             break;
  463.           
  464.           case EXT_COMMON:
  465.             /* first define the common symbol, then add the relocs */
  466.             add_symbol (&symbol_tab, hunk_num-1, file_ptr[0], 
  467.                      file_ptr[1+(file_ptr[0] & 0xffffff)],
  468.                     (char *)&file_ptr[1]);
  469.             file_ptr += 2+(file_ptr[0] & 0xffffff);
  470.  
  471.             /* now the references, translated into relocs */
  472.             for (n = file_ptr[0]; n--; )
  473.               add_reloc (&reloc_tab, hunk_num - 1, -1, file_ptr[n],
  474.                      2, 0, 0, symbol_tab.i - 1);
  475.             next_hunk (&file_ptr);
  476.             break;
  477.           
  478.           case EXT_REF8:
  479.           case EXT_REF16:
  480.           case EXT_REF32:
  481.           case EXT_DEXT8:
  482.           case EXT_DEXT16:
  483.           case EXT_DEXT32:
  484.             size = file_ptr[0] >> 24;
  485.             brel = size >= EXT_DEXT32;
  486.             size = (size == EXT_REF32 || size == EXT_DEXT32) ? 2 :
  487.                  ((size == EXT_REF16 || size == EXT_DEXT16) ? 1 : 0);
  488.             /* first define the symbol (as undefined ;-)), 
  489.              * then add the relocs */
  490.             add_symbol (&symbol_tab, hunk_num-1, file_ptr[0], 
  491.                     0, (char *)&file_ptr[1]);
  492.             file_ptr += 1+(file_ptr[0] & 0xffffff);
  493.  
  494.             /* now the references, translated into relocs */
  495.             for (n = file_ptr[0]; n; n--)
  496.               add_reloc (&reloc_tab, hunk_num - 1, -1, file_ptr[n],
  497.                      size, size < 2, brel, symbol_tab.i - 1);
  498.             next_hunk (&file_ptr);
  499.             break;
  500.  
  501.           default:
  502.             fprintf (stderr, 
  503.                  "Unknown symbol type %d, don't know how to handle!\n",
  504.                  file_ptr[0] >> 24);
  505.             /* can't continue, don't know how much to advance the file_ptr
  506.              * to reach the next valid hunk/block */
  507.             exit(20);
  508.             }
  509.         }
  510.       file_ptr++;
  511.       break;
  512.  
  513.         case HUNK_END:
  514. DP(("HUNK_END\n"));
  515.       break;
  516.  
  517.     default:
  518.       fprintf (stderr, "Unknown hunk type $%x, unit offset = $%x.\n",
  519.              file_ptr[-1], ((file_ptr-1)-*file_pptr) * 2);
  520.       /* can't continue, don't know how much to advance the file_ptr
  521.        * to reach the next valid hunk/block */
  522.       exit(20);
  523.     }
  524.       
  525.       if (file_ptr >= max_fp) break;
  526.     }
  527.  
  528.   *file_pptr = file_ptr >= max_fp ? max_fp : file_ptr-1;
  529.  
  530.   if (fd != -1)
  531.     emit_aout_file (fd, text, data, & hdr, 
  532.                 & code_hunks, & data_hunks, & bss_hunks,
  533.                 & reloc_tab, & symbol_tab, hunk_num);
  534. }
  535.  
  536.  
  537. void
  538. emit_aout_file (int fd, void *text, void *data, struct exec *hdr,
  539.         struct table *ch_tab, struct table *dh_tab, struct table *bh_tab,
  540.         struct table *reloc_tab,  struct table *symbol_tab, int max_hunk)
  541. {
  542.   int *code_hunks = ch_tab->base;
  543.   int *data_hunks = dh_tab->base;
  544.   int *bss_hunks  = bh_tab->base;
  545.   char htype[max_hunk];  
  546.   int i;
  547.   struct reloc *r;
  548.   struct symbol *s;
  549.   static struct table text_relocs = { 0, sizeof (struct reloc_info_68k), 0, 0 };
  550.   static struct table data_relocs = { 0, sizeof (struct reloc_info_68k), 0, 0 };
  551.  
  552.   text_relocs.i =
  553.     data_relocs.i = 0;
  554.  
  555.   /* convert hunk-numbers into N_TEXT,N_DATA,N_BSS types */
  556.   for (i = 0; i < ch_tab->i; i++) htype[code_hunks[i]] = N_TEXT;
  557.   for (i = 0; i < dh_tab->i; i++) htype[data_hunks[i]] = N_DATA;
  558.   for (i = 0; i < bh_tab->i; i++) htype[bss_hunks[i]]  = N_BSS;
  559.  
  560.   /* first conversion run. Change all hunk-numbers into N_TEXT, N_DATA and
  561.    * N_BSS rsp.
  562.    * (If you wanted to support multi-hunk files (ie. files with more than
  563.    * one code/data/bss hunk with size > 0) you'd want to do the necessary
  564.    * conversions here.)
  565.    */
  566.   for (i = 0, r = (struct reloc *)reloc_tab->base; i < reloc_tab->i; i++, r++)
  567.     {
  568.       r->from_hunk = htype[r->from_hunk];
  569.       if (r->to_hunk > -1)
  570.         r->to_hunk = htype[r->to_hunk];
  571.     }
  572.   for (i = 0, s = (struct symbol *)symbol_tab->base; i < symbol_tab->i; i++, s++)
  573.     s->hunk_num = htype[s->hunk_num];
  574.     
  575.   /* now convert the symbols into nlist's */
  576.   for (i = 0, s = (struct symbol *)symbol_tab->base; i < symbol_tab->i; i++, s++)
  577.     {
  578.       int nl_type = 0;
  579.  
  580.       switch (s->type)
  581.     {
  582.     case EXT_DEF:
  583.       /* externally visible symbol */
  584.       nl_type = N_EXT;
  585.       /* fall into */
  586.     
  587.     case EXT_SYMB:
  588.       nl_type |= s->hunk_num;
  589.       /* adjust DATA and BSS values to the one-seg model */
  590.       if (s->hunk_num == N_DATA)
  591.         s->value += hdr->a_text;
  592.       if (s->hunk_num == N_BSS)
  593.         s->value += hdr->a_text + hdr->a_data;
  594.       break;
  595.       
  596.     case EXT_ABS:
  597.       nl_type = N_ABS | N_EXT;
  598.       break;
  599.       
  600.     case EXT_COMMON:
  601.       /* ok for common as well, because the value field is only setup
  602.        * for common-symbols */
  603.  
  604.     case EXT_REF32:
  605.     case EXT_REF16:
  606.     case EXT_REF8:
  607.     case EXT_DEXT32:
  608.     case EXT_DEXT16:
  609.     case EXT_DEXT8:
  610.       nl_type = N_UNDF | N_EXT;
  611.       break;
  612.  
  613.     default:
  614.       fprintf (stderr, "What kind of symbol is THAT? (%d)\n", s->type);
  615.       break;
  616.     }
  617.  
  618.       s->type = nl_type;
  619.       s->pad1 = s->hunk_num = 0;  /* clear nl_other & nl_desc fields */
  620.     }
  621.     
  622.   /* now convert the reloc table. Adjust (like above) data/bss values to the
  623.    * one-segment model for local relocations */
  624.   for (i =  0, r = (struct reloc *)reloc_tab->base; i < reloc_tab->i; i++, r++)
  625.     {
  626.       struct reloc_info_68k rel;
  627.       uchar *core_addr;
  628.       
  629.       rel.r_address = r->offset;
  630.       core_addr = (r->from_hunk == N_TEXT) ? text : data;
  631.  
  632.       if (r->to_hunk == N_DATA)
  633.     if (r->size == 2)
  634.           *(ulong *)(core_addr + rel.r_address) += hdr->a_text;
  635.         else
  636.           fprintf (stderr, "%s reloc into N_DATA, what should I do?\n",
  637.            r->size == 1 ? "Short" : "Byte");
  638.       else if (r->to_hunk == N_BSS)
  639.     if (r->size == 2)
  640.           *(ulong *)(core_addr + rel.r_address) += hdr->a_text + hdr->a_data;
  641.         else
  642.           fprintf (stderr, "%s reloc into N_BSS, what should I do?\n",
  643.            r->size == 1 ? "Short" : "Byte");
  644.  
  645. #if 0
  646.       /* don't know, what went wrong, but this conversion surely converts
  647.        * _LVO calls wrong. I'm sure leaving this out will generate other bugs..
  648.        * sigh... */
  649.  
  650.       /* hmm... amigadog-hunks seem to do this in a strange way...
  651.        * Those relocs *are* treated as pcrel relocs by the linker (blink), 
  652.        * but they're not setup as such... geez, this hunk format.. */
  653.       if (r->pcrel)
  654.         switch (r->size)
  655.       {
  656.       case 2:
  657.         *(long *)(core_addr + rel.r_address)  -= rel.r_address;
  658.         break;
  659.  
  660.       case 1:
  661.         *(short *)(core_addr + rel.r_address) -= rel.r_address;
  662.         break;
  663.         
  664.       case 0:
  665.         *(char *)(core_addr + rel.r_address)  -= rel.r_address;
  666.         break;
  667.       }
  668. #endif
  669.  
  670.       rel.r_symbolnum = r->sym_num > -1 ? r->sym_num : r->to_hunk;
  671.       rel.r_pcrel     = r->pcrel;
  672.       rel.r_length    = r->size;
  673.       rel.r_extern    = r->sym_num > -1;
  674.       rel.r_baserel   = r->baserel;
  675.       rel.r_jmptable = rel.r_relative = 0;
  676.  
  677. DP(("r68: %s reloc\n", (r->from_hunk == N_TEXT) ? "text" : "data"));
  678.       add_table ((r->from_hunk == N_TEXT) ? & text_relocs : & data_relocs,
  679.             &rel);
  680.     }
  681.  
  682. DP(("r68: #tr = %d, #dr = %d\n", text_relocs.i, data_relocs.i));
  683.  
  684.   /* oky, fill out the rest of the header and dump everything */
  685.   hdr->a_syms = symbol_tab->i * sizeof (struct nlist);
  686.   hdr->a_trsize = text_relocs.i * sizeof (struct reloc_info_68k);
  687.   hdr->a_drsize = data_relocs.i * sizeof (struct reloc_info_68k);
  688.   *(ulong *)str_table = strtab_index;
  689.   write (fd, (char *)hdr, sizeof (*hdr));
  690.   if (hdr->a_text) write (fd, text, hdr->a_text);
  691.   if (hdr->a_data) write (fd, data, hdr->a_data);
  692.   if (hdr->a_trsize) write (fd, text_relocs.base, hdr->a_trsize);
  693.   if (hdr->a_drsize) write (fd, data_relocs.base, hdr->a_drsize);
  694.   if (hdr->a_syms) write (fd, symbol_tab->base, hdr->a_syms);
  695.   write (fd, str_table, strtab_index);
  696.   close (fd);
  697. }
  698.  
  699.  
  700.  
  701. int
  702. main (int argc, char *argv[])
  703. {
  704.   struct stat stb;
  705.   int ret_val = 0;
  706.   ulong *obj_pointer;
  707.   
  708.   FILE *fp;
  709.  
  710.   /* loop over all arguments. Can be either
  711.    *  o  object files
  712.    *  o  libraries (ALINK style for now)
  713.    */
  714.   while (*++argv)
  715.     {
  716.       if (stat (*argv, &stb) == -1)
  717.         {
  718.           fprintf (stderr, "%s: %s\n", *argv, strerror (errno));
  719.           continue;
  720.         }
  721.       
  722.       file_buf = file_buf ? realloc (file_buf, stb.st_size) 
  723.               : malloc (stb.st_size);
  724.       if (! file_buf)
  725.         {
  726.           fprintf (stderr, "%s: can't allocate %d byte of memory.\n", 
  727.            *argv, stb.st_size);
  728.       ret_val = 20;
  729.       break;
  730.     }
  731.     
  732.       if (!(fp = fopen (*argv, "r")))
  733.         {
  734.           fprintf (stderr, "Can't open %s: %s.\n", *argv, strerror (errno));
  735.       continue;
  736.         }
  737.       
  738.       /* read the file in at once */
  739.       if (fread (file_buf, stb.st_size, 1, fp) != 1)
  740.         {
  741.       fprintf (stderr, "Can't read %s: %s.\n", *argv, strerror (errno));
  742.       fclose (fp);
  743.       continue;
  744.     }
  745.     
  746.       /* oky, now digest the file (possibly more than one object file) */
  747.       for (obj_pointer = file_buf;
  748.        obj_pointer < (ulong *)((uchar *)file_buf + stb.st_size); )
  749.     digest_objfile (&obj_pointer, (ulong *)((uchar *)file_buf + stb.st_size));
  750.  
  751.       fclose (fp);
  752.     }
  753.  
  754.   return ret_val;
  755. }
  756.